﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace SnapLib
{
   public class ForeignListView : ForeignControl
   {
      LVITEM m_ListViewItem = new LVITEM();
      IntPtr m_ListViewItemPointer = IntPtr.Zero;
      IntPtr m_ListViewPointer_item = IntPtr.Zero;

      public ForeignListView(IntPtr parentCtrl, uint controlId) :
         base(parentCtrl, controlId)
      {
         m_ListViewItemPointer = Win32.VirtualAllocEx(AssociatedProcess.Handle, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(LVITEM)), Win32.MEM_COMMIT, Win32.PAGE_READWRITE);
         m_ListViewPointer_item = Win32.VirtualAllocEx(AssociatedProcess.Handle, IntPtr.Zero, 512, Win32.MEM_COMMIT, Win32.PAGE_READWRITE);
      }

      ~ForeignListView()
      {
         Win32.VirtualFreeEx(AssociatedProcess.Handle, m_ListViewItemPointer, (UIntPtr)0, Win32.MEM_RELEASE);
         Win32.VirtualFreeEx(AssociatedProcess.Handle, m_ListViewPointer_item, (UIntPtr)0, Win32.MEM_RELEASE);
      }

      public void EnsureVisible(int index)
      {
         Win32.SendMessage(m_hwnd, WindowsMessage.LVM_ENSUREVISIBLE, (uint)index, 0);
      }

      public string GetText(int index, short subItem)
      {

         m_ListViewItem.cchTextMax = 512;
         m_ListViewItem.SubItem = subItem;
         m_ListViewItem.iItem = index;
         m_ListViewItem.mask = (int)ListViewItemFlags.LVIF_TEXT;
         m_ListViewItem.pszText = m_ListViewPointer_item;

         Win32.SendMessage(m_hwnd, WindowsMessage.LVM_GETITEMTEXTW, (uint)index, (uint)m_ListViewItemPointer);

         int count;
         Win32.WriteProcessMemory(AssociatedProcess.Handle, m_ListViewItemPointer, ref m_ListViewItem, Marshal.SizeOf(typeof(LVITEM)), out count);
         Win32.SendMessage(m_hwnd, WindowsMessage.LVM_GETITEMA, (uint)index, (uint)m_ListViewItemPointer);

         byte[] t = AssociatedProcess.ReadProcessBytes(m_ListViewItemPointer, Marshal.SizeOf(typeof(LVITEM)));
         byte[] ListViewItemBuffer = AssociatedProcess.ReadProcessBytes(m_ListViewPointer_item, 512);

         return Encoding.ASCII.GetString(ListViewItemBuffer);
      }

      public string GetText(uint itemIndex)
      {
         StringBuilder sb = new StringBuilder(512);
         Win32.SendMessage(m_hwnd, WindowsMessage.LVM_GETITEMTEXTW, itemIndex, sb);
         return sb.ToString();
      }

      public int ItemCount
      {
         get
         {
            return (int)Win32.SendMessage(m_hwnd, WindowsMessage.LVM_GETITEMCOUNT, 0, 0);
         }
      }

      public uint SelectionCount
      {
         get
         {
            return Win32.SendMessage(m_hwnd, WindowsMessage.LVM_GETSELECTEDCOUNT, 0, 0);
         }
      }

      public uint SelectedIndex
      {
         get
         {
            return Win32.SendMessage(m_hwnd, WindowsMessage.LVM_GETHOTITEM, 0, 0);
         }
         set
         {
            m_ListViewItem.cchTextMax = 0;
            m_ListViewItem.SubItem = 0;
            m_ListViewItem.iItem = 0;
            m_ListViewItem.state = 0x3;
            m_ListViewItem.stateMask = 3;
            m_ListViewItem.mask = (int)ListViewItemFlags.LVIF_STATE;
            m_ListViewItem.pszText = IntPtr.Zero;

            int count;
            Win32.WriteProcessMemory(AssociatedProcess.Handle, m_ListViewItemPointer, ref m_ListViewItem, Marshal.SizeOf(typeof(LVITEM)), out count);
            Win32.SendMessage(m_hwnd, WindowsMessage.LVM_SETITEMSTATE, value, (uint)m_ListViewItemPointer);
         }
      }



   }

   #region ListView Structs
   public enum ListViewItemFlags
   {
      LVIF_TEXT = 0x0001,
      LVIF_IMAGE = 0x0002,
      LVIF_PARAM = 0x0004,
      LVIF_STATE = 0x0008,
      LVIF_INDENT = 0x0010,
      LVIF_NORECOMPUTE = 0x0800
   }

   [StructLayout(LayoutKind.Sequential)]
   internal struct LVITEM
   {
      public int mask;
      public int iItem;
      public int SubItem;
      public int state;
      public int stateMask;
      public IntPtr pszText;
      public int cchTextMax;
      public int iImage;
      internal int lParam;
      internal int iIndent;
   }
   #endregion

}
